前幾天我們說明了如何利用 Cypress 來撰寫端對端測試程式。這一篇來說明如何在 Cypress 設定環境變數,以及利用 Cypress 所提供的 fixture 來組織測試案例所需要的資料。
先前的登入頁面測試程式中,我們在 before()
與 after()
生命週期方法,透過 JSON Server 的 API 新增與移除測試的初始資料。這一篇就來說明,如何把其中的 API 路徑設定在 Cypress 的環境變數中,讓所有測試檔案可以使用。
describe('使用者登入', () => {
before(() => {
cy.request('POST', 'http://localhost:3000/users', {
id: 'userA',
password: '1234567',
});
});
after(() => {
cy.request('DELETE', 'http://localhost:3000/users/userA');
});
});
在 Cypress 中,可以把需要的環境變數設定在組態檔案內。因此,我們在 cypress.config.ts
檔案中的 env
屬性加入 apiUrl
來定義後端服務的路徑。
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:4200',
supportFile: false,
env: {
apiUrl: 'http://localhost:3000',
},
},
});
除非之外,也可以新增 cypress.env.json
檔案來專職記錄 Cypress 環境變數。
{
"apiUrl": "http://localhost:3000"
}
也可以在 Cypress 的 CLI 命令加上 --env
參數來指定環境變數。
cypress run --env apiUrl=http://localhost:3000
而在使用上會使用 Cypress.env()
方法來取得所需要的環境變數。因此,我們可以修改 login.cy.ts
檔案,利用 apiUrl
環境變數來處理初始資料。
before(() => {
cy.request('POST', `${Cypress.env('apiUrl')}/users`, {
id: 'userA',
password: '1234567',
});
});
after(() => {
cy.request('DELETE', `${Cypress.env('apiUrl')}/users/userA`);
});
fixture()
取得測試資料在使用者登入的測試案例中,我們分別會用三種不同的測試資料來測試帳號不存在、登入成功與失敗等案例。
describe('登入作業', () => {
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('mat-error').should('exist').and('have.text', '此帳號不存在');
cy.get('button').contains('登入').parent().should('be.disabled');
});
it('當輸入錯誤帳號密碼, 應登入失敗', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userA');
cy.get('input[type=password]').type('00000');
cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入失敗');
});
it('當輸入正確帳號密碼, 應登入成功', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userA');
cy.get('input[type=password]').type('1234567');
cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入成功');
});
});
然而,在 cypress
資料夾下存在著 fixture
資料,是用來放測試案例所需要用到的資料。因此我們可以這個資料夾下新增 users
目錄,並加入帳號不存在 (id-not-exist.json
)、登入成功 (login-success.json
) 與失敗 (login-failed.json
) 三個案例所需要的 json 檔。
{
"id": "userA",
"password": "1234567"
}
上面的 JSON 是針對使用者登入成功的案例所需要的測試資料,此時就可以在測試程式中利用 fixture()
方法來取得。如下面程式,fixture()
方法會傳入測試資料所在的路徑,Cypress 會去 cypress\fixture
資料夾內,依 json
、js
、coffee
、html
、txt
、csv
等順序去找尋並取得測試資料。由於在 Cypress 內的方法都是非同步處理,因此我們會利用 then()
方法來取得的使用者資料並進行測試。
it('當輸入正確帳號密碼, 應登入成功', () => {
cy.fixture('users/login-success').then(({ id, password }) => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type(id);
cy.get('input[type=password]').type(password);
cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入成功');
});
});
今天利用 Cypress 環境變數設定資料庫設定所需的路徑,也使用 Cypress 所提供的 fixture()
來整理測試案例所需要的測試資料,完整的測試程式可以參考 GitHub。由於端對點測試是從使用者操作的角度去撰寫,因而在測試程式中會重覆地使用取得頁面元素的程式。接下來,會說明如何利用 Cypress 的別名與自訂命令來降低程式碼的重覆。